﻿using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;

namespace Core.ApiClient.App_Code.Swagger_Attribute
{
    public class ApplyTagDescriptions : IDocumentFilter
    {

        static List<Tag> tags = new List<Tag>();

        /// <summary>
        /// 初始化文档注释
        /// </summary>
        static ApplyTagDescriptions()
        {
            string xmlpath =
                Path.Combine(AppContext.BaseDirectory, "Swagger.xml");

            var dics =
                new ApplyTagDescriptions().GetControllerDesc(xmlpath);

            if (null != dics && dics.Count > 0)
                foreach (var dic in dics)
                    tags.Add(new Tag {Name = dic.Key, Description = dic.Value});

        }

        /// <summary>
        /// 添加控制器模块说明
        /// </summary>
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            swaggerDoc.Tags = tags;
        }

        /// <summary>
        /// 从API文档中读取控制器描述
        /// </summary>
        /// <returns>所有控制器描述</returns>
        public ConcurrentDictionary<string, string> GetControllerDesc(string xmlpath)
        {
            ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>();
            if (File.Exists(xmlpath))
            {
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load(xmlpath);
                string type = string.Empty, path = string.Empty, controllerName = string.Empty;

                string[] arrPath;
                int length = -1, cCount = "Controller".Length;
                XmlNode summaryNode = null;
                foreach (XmlNode node in xmldoc.SelectNodes("//member"))
                {
                    type = node.Attributes["name"].Value;
                    if (type.StartsWith("T:") && type.Contains("Controllers"))
                    {
                        //控制器
                        arrPath = type.Split('.');
                        length = arrPath.Length;
                        controllerName = arrPath[length - 1];
                        if (controllerName.EndsWith("Controller"))
                        {
                            //获取控制器注释
                            summaryNode = node.SelectSingleNode("summary");
                            string key = controllerName.Remove(controllerName.Length - cCount, cCount);
                            if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
                            {
                                controllerDescDict.TryAdd
                                    (key, 
                                    $" [{arrPath[3]}] " + summaryNode.InnerText.Trim().Replace("Controller",""));
                            }
                        }
                    }
                }
            }
            return controllerDescDict;
        }
    }

}
